package com.sf.dlb.service;

import com.mongodb.*;
import com.sf.dlb.config.Global;
import com.sf.dlb.constant.ResponseConstant;
import com.sf.dlb.jpa.model.TokenEntity;
import com.sf.dlb.mongo.model.VisitorInfo;
import com.sf.dlb.mongo.repository.VisitorInfoRepository;
import com.sf.dlb.utils.DateUtils;
import com.sf.dlb.utils.GsonUtils;
import com.sf.dlb.utils.MD5Util;
import com.sf.dlb.utils.ResultVOUtil;
import com.sf.dlb.vo.ResultVO;
import com.sf.dlb.vo.VisitorInfoVO;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * Created by jing.tan on 2018/5/21.
 */
@Service
public class VisitorInfoService {
    private static Logger logger = LoggerFactory.getLogger(VisitorInfoService.class);
    @Autowired
    private Global global;
    @Autowired
    private VisitorInfoRepository visitorInfoRepository;
    @Autowired
    private MongoTemplate mongoTemplate;
    /**
     * 创建游客
     * @return
     */
    @Transactional
    public ResultVO createVisitorInfo(String deviceNumber,String deviceType){
        logger.info(" createVisitorInfo start deviceNumber={},deviceType={}",deviceNumber,deviceType);
        //查询此游客是否存在
        VisitorInfo visitorInfo=visitorInfoRepository.findByDeviceNumberAndAndDelFlag(deviceNumber,"0");
        if(visitorInfo!=null){
            logger.info("游客已经存在");
            VisitorInfoVO visitorInfoVO=userBeanToVo(visitorInfo);
            return ResultVOUtil.success(visitorInfoVO);
        }else{
            //不存在-插入
            visitorInfo=new VisitorInfo();
            long visitorId=1+(getCurrentVisitorId());
            visitorInfo.setVisitorId(visitorId);
            visitorInfo.setDeviceType(deviceType);
            visitorInfo.setDeviceNumber(deviceNumber);
            visitorInfo.setName("游客"+visitorId);
            visitorInfo.setLoginFlag("0");
            visitorInfo.setRegistFlag("0");
            visitorInfo.setCreateDate(new Date());
            visitorInfo.setUpdateDate(new Date());
            generaAndSaveToken(visitorInfo);
            visitorInfoRepository.save(visitorInfo);
            VisitorInfoVO visitorInfoVO=userBeanToVo(visitorInfo);
            return ResultVOUtil.success(visitorInfoVO);
        }
    }
    /**
     * 得到当前最大的visitorId
     */
    public int getCurrentVisitorId(){
        DBObject groupFields = new BasicDBObject( "_id", "null");
        groupFields.put("visitorId", new BasicDBObject( "$max", "$visitorId"));
        DBObject group = new BasicDBObject("$group", groupFields);
        List<DBObject> dbObject=new ArrayList<>();
        dbObject.add(group);
        AggregationOutput aggregationOutput=mongoTemplate.getCollection("visitorInfo").aggregate(dbObject);
        Iterable<DBObject> dbObjects=aggregationOutput.results();
        int visitorIdMax=0;
        for(DBObject dbObject1:dbObjects){
            visitorIdMax=Integer.parseInt(dbObject1.get("visitorId").toString());
        }
        return visitorIdMax;
    }
    /**
     * 更新游客注册状态
     */
    @Transactional
    public void updateRegistFlag(String deviceNumber){
        logger.info("updateRegistFlag start");
        if(StringUtils.isBlank(deviceNumber)){
            return;
        }
        VisitorInfo visitorInfo = visitorInfoRepository.findByDeviceNumberAndAndDelFlag(deviceNumber,"0");
        if(null==visitorInfo){
            logger.info("updateRegistFlag null==visitorInfo");
        }
        visitorInfo.setRegistFlag("1");
        visitorInfo.setUpdateDate(new Date());
        visitorInfoRepository.save(visitorInfo);
    }
    /**
     * 生成并保存token
     * @param visitorInfo
     * @return
     */
    @Transactional
    public TokenEntity generaAndSaveToken(VisitorInfo visitorInfo){
        logger.info("generaAndSaveToken start visitorInfo={}", GsonUtils.getInstance().toJson(visitorInfo));
        TokenEntity tokenEntity=new TokenEntity();
        String uuid= UUID.randomUUID().toString().replace("-","");
        Date tokenCreateDate=new Date();
        Long visitorId=visitorInfo.getVisitorId();
        String md5Str=visitorId
                +DateUtils.formatDate(tokenCreateDate)
                +uuid;
        //添加游客前缀
        String token=global.user_visitor_token_prefix+MD5Util.MD5(md5Str);
        tokenEntity.setToken(token);
        tokenEntity.setCreateDate(tokenCreateDate);
        tokenEntity.setExpiresIn(Long.valueOf(global.token_valid_time));
        tokenEntity.setUserId(visitorId+"");
        //保存
        visitorInfo.setToken(tokenEntity.getToken());
        visitorInfo.setTokenTime(tokenEntity.getCreateDate());
        visitorInfo.setUpdateDate(new Date());
        return tokenEntity;
    }
    /**
     * token+校验
     *
     * @return
     */
    public ResultVO getTokenChekout(HttpServletRequest request) {
        //判断token是否合法
        String token=request.getHeader(global.token_request_header_key);
        logger.info("getTokenChekout token === " + token);
        if(StringUtils.isEmpty(token)){
            return ResultVOUtil.error(ResponseConstant.ERROR_TOKEN_NULL, "token不能为空");
        }
        if(!token.startsWith(global.token_request_header_value_prefix)){
            return ResultVOUtil.error(ResponseConstant.ERROR_TOKEN_ILLEGAL, "token不合法");
        }
        if(token.length()<=global.token_request_header_value_prefix.length()+1){
            return ResultVOUtil.error(ResponseConstant.ERROR_TOKEN_ILLEGAL, "token不合法");
        }
        token=token.substring(global.token_request_header_value_prefix.length()+1);
        //token是否存在
        VisitorInfo visitorInfo = visitorInfoRepository.findByTokenAndDelFlag(token,"0");
        if(null==visitorInfo){
            return ResultVOUtil.error(ResponseConstant.ERROR_TOKEN_THERE_NO, "token不存在");
        }
        TokenEntity tokenEntity=new TokenEntity();
        tokenEntity.setUserId(visitorInfo.getVisitorId()+"");
        tokenEntity.setToken(visitorInfo.getToken());
        tokenEntity.setCreateDate(visitorInfo.getTokenTime());
        tokenEntity.setExpiresIn(Long.valueOf(global.token_valid_time));
        return ResultVOUtil.success(tokenEntity);
    }
    /**
     * VO转换
     * @return
     */
    public VisitorInfoVO userBeanToVo(VisitorInfo visitorInfo){
        VisitorInfoVO visitorInfoVO=new VisitorInfoVO();
        BeanUtils.copyProperties(visitorInfo,visitorInfoVO);
        visitorInfoVO.setVisitorId(visitorInfo.getVisitorId()+"");
        visitorInfoVO.setCreateDate(visitorInfo.getCreateDate().getTime());
        return visitorInfoVO;
    }
}
